home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / yacc / flexyacc / aflex.lha / aflex / src / parse.a < prev    next >
Text File  |  1993-05-31  |  24KB  |  1,044 lines

  1.  
  2. with Parse_Tokens, Parse_Goto, Parse_Shift_Reduce, Text_IO, scanner;
  3. with NFA, ccl, misc, misc_defs, sym, ecs, aflex_scanner;
  4. with tstring, int_io, main_body, text_io, external_file_manager;
  5. use aflex_scanner, external_file_manager;
  6.  
  7. package parser is
  8.   procedure build_eof_action;
  9.   procedure yyerror(msg: string);
  10.   procedure YYParse;
  11.   def_rule:integer;
  12. end parser;
  13.  
  14. package body parser is
  15. -- build_eof_action - build the "<<EOF>>" action for the active start
  16. --                    conditions
  17.  
  18. use text_io, misc_defs;
  19. procedure build_eof_action is
  20. begin
  21.     text_io.put( temp_action_file, "when " );
  22.     for i in 1..actvp loop
  23.     if ( sceof(actvsc(i)) ) then
  24.         text_io.put( Standard_Error,
  25.         "multiple <<EOF>> rules for start condition ");
  26.         tstring.put( Standard_Error, scname(actvsc(i)));
  27.         main_body.aflexend(1);
  28.     else
  29.         sceof(actvsc(i)) := true;
  30.         text_io.put( temp_action_file, "YY_END_OF_BUFFER +" );
  31.         tstring.put( temp_action_file,  scname(actvsc(i)) );
  32.         text_io.put_line( temp_action_file, " + 1 " );
  33.         if (i /= actvp) then
  34.             text_io.put_line( temp_action_file, " |" );
  35.         else
  36.             text_io.put_line( temp_action_file, " =>" );
  37.         end if;
  38.         end if;
  39.     end loop;
  40.     misc.line_directive_out( temp_action_file );
  41. end build_eof_action;
  42.  
  43. --  yyerror - eat up an error message from the parser
  44. -- 
  45. --  synopsis
  46. --     char msg[];
  47. --     yyerror( msg );
  48.  
  49. procedure yyerror( msg : string ) is
  50. begin
  51. null;
  52. end yyerror;
  53.  
  54. use  Parse_Goto, Parse_Shift_Reduce, Text_IO, misc_defs, tstring;
  55. procedure YYParse is
  56.  
  57.    -- Rename User Defined Packages to Internal Names.
  58.     package yy_goto_tables         renames
  59.       Parse_Goto;
  60.     package yy_shift_reduce_tables renames
  61.       Parse_Shift_Reduce;
  62.     package yy_tokens              renames
  63.       Parse_Tokens;
  64.  
  65.    use yy_tokens, yy_goto_tables, yy_shift_reduce_tables;
  66.  
  67.    procedure yyerrok;
  68.    procedure yyclearin;
  69.  
  70.    package yy is
  71.  
  72.        -- the size of the value and state stacks
  73.        stack_size : constant Natural := 300;
  74.  
  75.        -- subtype rule         is natural;
  76.        subtype parse_state  is natural;
  77.        -- subtype nonterminal  is integer;
  78.  
  79.        -- encryption constants
  80.        default           : constant := -1;
  81.        first_shift_entry : constant :=  0;
  82.        accept_code       : constant := -1001;
  83.        error_code        : constant := -1000;
  84.  
  85.        -- stack data used by the parser
  86.        tos                : natural := 0;
  87.        value_stack        : array(0..stack_size) of yy_tokens.yystype;
  88.        state_stack        : array(0..stack_size) of parse_state;
  89.  
  90.        -- current input symbol and action the parser is on
  91.        action             : integer;
  92.        rule_id            : rule;
  93.        input_symbol       : yy_tokens.token;
  94.  
  95.  
  96.        -- error recovery flag
  97.        error_flag : natural := 0;
  98.           -- indicates  3 - (number of valid shifts after an error occurs)
  99.  
  100.        look_ahead : boolean := true;
  101.        index      : integer;
  102.  
  103.        -- Is Debugging option on or off
  104.         DEBUG : constant boolean := FALSE;
  105.  
  106.     end yy;
  107.  
  108.  
  109.     function goto_state
  110.       (state : yy.parse_state;
  111.        sym   : nonterminal) return yy.parse_state;
  112.  
  113.     function parse_action
  114.       (state : yy.parse_state;
  115.        t     : yy_tokens.token) return integer;
  116.  
  117.     pragma inline(goto_state, parse_action);
  118.  
  119.  
  120.     function goto_state(state : yy.parse_state;
  121.                         sym   : nonterminal) return yy.parse_state is
  122.         index : integer;
  123.     begin
  124.         index := goto_offset(state);
  125.         while  integer(goto_matrix(index).nonterm) /= sym loop
  126.             index := index + 1;
  127.         end loop;
  128.         return integer(goto_matrix(index).newstate);
  129.     end goto_state;
  130.  
  131.  
  132.     function parse_action(state : yy.parse_state;
  133.                           t     : yy_tokens.token) return integer is
  134.         index      : integer;
  135.         tok_pos    : integer;
  136.         default    : constant integer := -1;
  137.     begin
  138.         tok_pos := yy_tokens.token'pos(t);
  139.         index   := shift_reduce_offset(state);
  140.         while integer(shift_reduce_matrix(index).t) /= tok_pos and then
  141.               integer(shift_reduce_matrix(index).t) /= default
  142.         loop
  143.             index := index + 1;
  144.         end loop;
  145.         return integer(shift_reduce_matrix(index).act);
  146.     end parse_action;
  147.  
  148. -- error recovery stuff
  149.  
  150.     procedure handle_error is
  151.       temp_action : integer;
  152.     begin
  153.  
  154.       if yy.error_flag = 3 then -- no shift yet, clobber input.
  155.       if yy.debug then
  156.           put_line("Ayacc.YYParse: Error Recovery Clobbers " &
  157.                    yy_tokens.token'image(yy.input_symbol));
  158.       end if;
  159.         if yy.input_symbol = yy_tokens.end_of_input then  -- don't discard,
  160.         if yy.debug then
  161.             put_line("Ayacc.YYParse: Can't discard END_OF_INPUT, quiting...");
  162.         end if;
  163.         raise yy_tokens.syntax_error;
  164.         end if;
  165.  
  166.             yy.look_ahead := true;   -- get next token
  167.         return;                  -- and try again...
  168.     end if;
  169.  
  170.     if yy.error_flag = 0 then -- brand new error
  171.         yyerror("Syntax Error");
  172.     end if;
  173.  
  174.     yy.error_flag := 3;
  175.  
  176.     -- find state on stack where error is a valid shift --
  177.  
  178.     if yy.debug then
  179.         put_line("Ayacc.YYParse: Looking for state with error as valid shift");
  180.     end if;
  181.  
  182.     loop
  183.         if yy.debug then
  184.         put_line("Ayacc.YYParse: Examining State " &
  185.               yy.parse_state'image(yy.state_stack(yy.tos)));
  186.         end if;
  187.         temp_action := parse_action(yy.state_stack(yy.tos), error);
  188.  
  189.             if temp_action >= yy.first_shift_entry then
  190.                 if yy.tos = yy.stack_size then
  191.                     put_line(" Stack size exceeded on state_stack");
  192.                     raise yy_Tokens.syntax_error;
  193.                 end if;
  194.                 yy.tos := yy.tos + 1;
  195.                 yy.state_stack(yy.tos) := temp_action;
  196.                 exit;
  197.             end if;
  198.  
  199.         Decrement_Stack_Pointer :
  200.         begin
  201.           yy.tos := yy.tos - 1;
  202.         exception
  203.           when Constraint_Error =>
  204.             yy.tos := 0;
  205.         end Decrement_Stack_Pointer;
  206.  
  207.         if yy.tos = 0 then
  208.           if yy.debug then
  209.             put_line("Ayacc.YYParse: Error recovery popped entire stack, aborting...");
  210.           end if;
  211.           raise yy_tokens.syntax_error;
  212.         end if;
  213.     end loop;
  214.  
  215.     if yy.debug then
  216.         put_line("Ayacc.YYParse: Shifted error token in state " &
  217.               yy.parse_state'image(yy.state_stack(yy.tos)));
  218.     end if;
  219.  
  220.     end handle_error;
  221.  
  222.    -- print debugging information for a shift operation
  223.    procedure shift_debug(state_id: yy.parse_state; lexeme: yy_tokens.token) is
  224.    begin
  225.        put_line("Ayacc.YYParse: Shift "& yy.parse_state'image(state_id)&" on input symbol "&
  226.                yy_tokens.token'image(lexeme) );
  227.    end;
  228.  
  229.    -- print debugging information for a reduce operation
  230.    procedure reduce_debug(rule_id: rule; state_id: yy.parse_state) is
  231.    begin
  232.        put_line("Ayacc.YYParse: Reduce by rule "&rule'image(rule_id)&" goto state "&
  233.                yy.parse_state'image(state_id));
  234.    end;
  235.  
  236.    -- make the parser believe that 3 valid shifts have occured.
  237.    -- used for error recovery.
  238.    procedure yyerrok is
  239.    begin
  240.        yy.error_flag := 0;
  241.    end yyerrok;
  242.  
  243.    -- called to clear input symbol that caused an error.
  244.    procedure yyclearin is
  245.    begin
  246.        -- yy.input_symbol := yylex;
  247.        yy.look_ahead := true;
  248.    end yyclearin;
  249.  
  250.  
  251. begin
  252.     -- initialize by pushing state 0 and getting the first input symbol
  253.     yy.state_stack(yy.tos) := 0;
  254.  
  255.     loop
  256.  
  257.         yy.index := shift_reduce_offset(yy.state_stack(yy.tos));
  258.         if integer(shift_reduce_matrix(yy.index).t) = yy.default then
  259.             yy.action := integer(shift_reduce_matrix(yy.index).act);
  260.         else
  261.             if yy.look_ahead then
  262.                 yy.look_ahead   := false;
  263.                 yy.input_symbol := yylex;
  264.             end if;
  265.             yy.action :=
  266.              parse_action(yy.state_stack(yy.tos), yy.input_symbol);
  267.         end if;
  268.  
  269.         if yy.action >= yy.first_shift_entry then  -- SHIFT
  270.  
  271.             if yy.debug then
  272.                 shift_debug(yy.action, yy.input_symbol);
  273.             end if;
  274.  
  275.             -- Enter new state
  276.             if yy.tos = yy.stack_size then
  277.                 put_line(" Stack size exceeded on state_stack");
  278.                 raise yy_Tokens.syntax_error;
  279.             end if;
  280.             yy.tos := yy.tos + 1;
  281.             yy.state_stack(yy.tos) := yy.action;
  282.             yy.value_stack(yy.tos) := yylval;
  283.  
  284.         if yy.error_flag > 0 then  -- indicate a valid shift
  285.             yy.error_flag := yy.error_flag - 1;
  286.         end if;
  287.  
  288.             -- Advance lookahead
  289.             yy.look_ahead := true;
  290.  
  291.         elsif yy.action = yy.error_code then       -- ERROR
  292.             handle_error;
  293.  
  294.         elsif yy.action = yy.accept_code then
  295.             if yy.debug then
  296.                 put_line("Ayacc.YYParse: Accepting Grammar...");
  297.             end if;
  298.             exit;
  299.  
  300.         else -- Reduce Action
  301.  
  302.             -- Convert action into a rule
  303.             yy.rule_id  := -1 * yy.action;
  304.  
  305.             -- Execute User Action
  306.             -- user_action(yy.rule_id);
  307.             case yy.rule_id is
  308.  
  309. when  1 =>
  310. --#line  44
  311.  -- add default rule
  312.  
  313.             pat := ccl.cclinit;
  314.             ccl.cclnegate( pat );
  315.  
  316.             def_rule := nfa.mkstate( -pat );
  317.  
  318.             nfa.finish_rule( def_rule, false, 0, 0 );
  319.  
  320.             for i in 1 .. lastsc loop
  321.                 scset(i) := nfa.mkbranch( scset(i), def_rule );
  322.             end loop;
  323.             
  324.             if ( spprdflt ) then
  325.                 text_io.put(temp_action_file,
  326.                     "raise AFLEX_SCANNER_JAMMED;");
  327.             else
  328.                 text_io.put( temp_action_file, "ECHO" );
  329.  
  330.             text_io.put_line( temp_action_file, ";" );
  331.             end if;
  332.             
  333.  
  334. when  2 =>
  335. --#line  69
  336.  
  337.             -- initialize for processing rules
  338.  
  339.                    -- create default DFA start condition
  340.             sym.scinstal( tstring.vstr("INITIAL"), false );
  341.             
  342.  
  343. when  5 =>
  344. --#line  80
  345.  misc.synerr( "unknown error processing section 1" );
  346.  
  347. when  7 =>
  348. --#line  87
  349.  
  350.              -- these productions are separate from the s1object
  351.              -- rule because the semantics must be done before
  352.              -- we parse the remainder of an s1object
  353.             
  354.  
  355.             xcluflg := false;
  356.             
  357.  
  358. when  8 =>
  359. --#line  97
  360.  xcluflg := true; 
  361.  
  362. when  9 =>
  363. --#line  101
  364.  sym.scinstal( nmstr, xcluflg ); 
  365.  
  366. when  10 =>
  367. --#line  104
  368.  sym.scinstal( nmstr, xcluflg ); 
  369.  
  370. when  11 =>
  371. --#line  107
  372.  misc.synerr( "bad start condition list" ); 
  373.  
  374. when  14 =>
  375. --#line  115
  376.  
  377.             -- initialize for a parse of one rule
  378.             trlcontxt := false;
  379.             variable_trail_rule := false;
  380.             varlength := false;
  381.             trailcnt := 0;
  382.             headcnt := 0;
  383.             rulelen := 0;
  384.             current_state_enum := STATE_NORMAL;
  385.             previous_continued_action := continued_action;
  386.             nfa.new_rule;
  387.             
  388.  
  389. when  15 =>
  390. --#line  130
  391.  
  392.             pat := nfa.link_machines( 
  393. yy.value_stack(yy.tos-1), 
  394. yy.value_stack(yy.tos) );
  395.             nfa.finish_rule( pat, variable_trail_rule,
  396.                      headcnt, trailcnt );
  397.  
  398.             for i in 1 .. actvp loop
  399.                 scbol(actvsc(i)) :=
  400.                 nfa.mkbranch( scbol(actvsc(i)), pat );
  401.             end loop;    
  402.                 
  403.             if ( not bol_needed ) then
  404.                 bol_needed := true;
  405.  
  406.                 if ( performance_report ) then
  407.                 text_io.put( Standard_Error,
  408.             "'^' operator results in sub-optimal performance");
  409.                     text_io.new_line(Standard_Error);
  410.                             end if;
  411.             end if;
  412.             
  413.  
  414. when  16 =>
  415. --#line  152
  416.  
  417.             pat := nfa.link_machines( 
  418. yy.value_stack(yy.tos-1), 
  419. yy.value_stack(yy.tos) );
  420.             nfa.finish_rule( pat, variable_trail_rule,
  421.                      headcnt, trailcnt );
  422.  
  423.             for i in 1 .. actvp loop
  424.                 scset(actvsc(i)) := 
  425.                 nfa.mkbranch( scset(actvsc(i)), pat );
  426.             end loop;
  427.                 
  428.  
  429. when  17 =>
  430. --#line  163
  431.  
  432.             pat := nfa.link_machines( 
  433. yy.value_stack(yy.tos-1), 
  434. yy.value_stack(yy.tos) );
  435.             nfa.finish_rule( pat, variable_trail_rule,
  436.                      headcnt, trailcnt );
  437.  
  438.             -- add to all non-exclusive start conditions,
  439.             -- including the default (0) start condition
  440.  
  441.             for i in 1 .. lastsc loop
  442.                 if ( not scxclu(i) ) then
  443.                 scbol(i) := nfa.mkbranch( scbol(i), pat );
  444.                 end if;    
  445.             end loop;
  446.  
  447.             if ( not bol_needed ) then
  448.                 bol_needed := true;
  449.  
  450.                 if ( performance_report ) then
  451.                 text_io.put( Standard_Error,
  452.             "'^' operator results in sub-optimal performance");
  453.                     text_io.new_line(Standard_Error);
  454.                 end if;
  455.             end if;
  456.                         
  457.  
  458. when  18 =>
  459. --#line  188
  460.  
  461.             pat := nfa.link_machines( 
  462. yy.value_stack(yy.tos-1), 
  463. yy.value_stack(yy.tos) );
  464.             nfa.finish_rule( pat, variable_trail_rule,
  465.                      headcnt, trailcnt );
  466.  
  467.             for i in 1 .. lastsc loop
  468.                 if ( not scxclu(i) ) then
  469.                 scset(i) := nfa.mkbranch( scset(i), pat );
  470.                 end if;
  471.             end loop;
  472.             
  473.  
  474. when  19 =>
  475. --#line  201
  476.  build_eof_action; 
  477.  
  478. when  20 =>
  479. --#line  204
  480.  
  481.             -- this EOF applies only to the INITIAL start cond.
  482.             actvp := 1;
  483.             actvsc(actvp) := 1;
  484.             build_eof_action;
  485.             
  486.  
  487. when  21 =>
  488. --#line  212
  489.  misc.synerr( "unrecognized rule" ); 
  490.  
  491. when  23 =>
  492. --#line  219
  493.  
  494.             scnum := sym.sclookup( nmstr );
  495.             if (scnum = 0 ) then
  496.                     text_io.put( Standard_Error,
  497.                      "undeclared start condition ");
  498.                     tstring.put( Standard_Error, nmstr );
  499.                 main_body.aflexend( 1 );
  500.             else
  501.               actvp := actvp + 1;
  502.                 actvsc(actvp) := scnum;
  503.             end if;
  504.             
  505.  
  506. when  24 =>
  507. --#line  233
  508.  
  509.             scnum := sym.sclookup( nmstr );
  510.             if (scnum = 0 ) then
  511.                     text_io.put( Standard_Error,
  512.                     "undeclared start condition ");
  513.                     tstring.put( Standard_Error,     nmstr );
  514.                 main_body.aflexend ( 1 );
  515.             else
  516.                 actvp := 1;
  517.                 actvsc(actvp) := scnum;
  518.             end if;
  519.             
  520.  
  521. when  25 =>
  522. --#line  247
  523.  misc.synerr( "bad start condition list" ); 
  524.  
  525. when  26 =>
  526. --#line  251
  527.  
  528.             if trlcontxt then
  529.                 misc.synerr( "trailing context used twice" );
  530.                 
  531. yyval := nfa.mkstate( SYM_EPSILON );
  532.             else
  533.                 trlcontxt := true;
  534.  
  535.                 if ( not varlength ) then
  536.                 headcnt := rulelen;
  537.                 end if;
  538.  
  539.                 rulelen := rulelen + 1;
  540.                 trailcnt := 1;
  541.  
  542.                 eps := nfa.mkstate( SYM_EPSILON );
  543.                 
  544. yyval := nfa.link_machines( eps,
  545.                       nfa.mkstate( CHARACTER'POS(ASCII.LF) ) );
  546.                         end if;
  547.             
  548.  
  549. when  27 =>
  550. --#line  272
  551.  
  552.                 
  553. yyval := nfa.mkstate( SYM_EPSILON );
  554.  
  555.             if ( trlcontxt ) then
  556.                 if ( varlength and (headcnt = 0) ) then
  557.                 -- both head and trail are variable-length
  558.                 variable_trail_rule := true;
  559.                 else
  560.                 trailcnt := rulelen;
  561.                 end if;
  562.                         end if;
  563.                 
  564.  
  565. when  28 =>
  566. --#line  287
  567.  
  568.             varlength := true;
  569.  
  570.             
  571. yyval := nfa.mkor( 
  572. yy.value_stack(yy.tos-2), 
  573. yy.value_stack(yy.tos) );
  574.             
  575.  
  576. when  29 =>
  577. --#line  294
  578.  
  579.             if ( transchar(lastst(
  580. yy.value_stack(yy.tos))) /= SYM_EPSILON ) then
  581.                 -- provide final transition \now/ so it
  582.                 -- will be marked as a trailing context
  583.                 -- state
  584.  
  585.                 
  586. yy.value_stack(yy.tos) := nfa.link_machines( 
  587. yy.value_stack(yy.tos), nfa.mkstate( SYM_EPSILON ) );
  588.             end if;
  589.  
  590.             nfa.mark_beginning_as_normal( 
  591. yy.value_stack(yy.tos) );
  592.             current_state_enum := STATE_NORMAL;
  593.  
  594.             if ( previous_continued_action ) then
  595.                 -- we need to treat this as variable trailing
  596.                 -- context so that the backup does not happen
  597.                 -- in the action but before the action switch
  598.                 -- statement.  If the backup happens in the
  599.                 -- action, then the rules "falling into" this
  600.                 -- one's action will *also* do the backup,
  601.                 -- erroneously.
  602.  
  603.                     if ( (not varlength) or  headcnt /= 0 ) then
  604.                      text_io.put( Standard_Error,
  605.                               "alex: warning - trailing context rule at line");
  606.                                      int_io.put(Standard_Error, linenum);
  607.                      text_io.put( Standard_Error,
  608.                            "made variable because of preceding '|' action" );
  609.                                      int_io.put(Standard_Error, linenum);
  610.                                 end if;
  611.  
  612.                 -- mark as variable
  613.                 varlength := true;
  614.                 headcnt := 0;
  615.                         end if;
  616.             
  617.             if ( varlength and (headcnt = 0) ) then
  618.                 -- variable trailing context rule
  619.                 -- mark the first part of the rule as the accepting
  620.                 -- "head" part of a trailing context rule
  621.  
  622.                 -- by the way, we didn't do this at the beginning
  623.                 -- of this production because back then
  624.                 -- current_state_enum was set up for a trail
  625.                 -- rule, and add_accept() can create a new
  626.                 -- state ...
  627.  
  628.                 nfa.add_accept( 
  629. yy.value_stack(yy.tos-1),
  630.                                    misc.set_yy_trailing_head_mask(num_rules) );
  631.                         end if;
  632.  
  633.             
  634. yyval := nfa.link_machines( 
  635. yy.value_stack(yy.tos-1), 
  636. yy.value_stack(yy.tos) );
  637.             
  638.  
  639. when  30 =>
  640. --#line  348
  641.  
  642. yyval := 
  643. yy.value_stack(yy.tos); 
  644.  
  645. when  31 =>
  646. --#line  353
  647.  
  648.             -- this rule is separate from the others for "re" so
  649.             -- that the reduction will occur before the trailing
  650.             -- series is parsed
  651.  
  652.             if ( trlcontxt ) then
  653.                 misc.synerr( "trailing context used twice" );
  654.             else
  655.                 trlcontxt := true;
  656.             end if;    
  657.  
  658.             if ( varlength ) then
  659.                 -- we hope the trailing context is fixed-length
  660.                 varlength := false;
  661.             else
  662.                 headcnt := rulelen;
  663.             end if;    
  664.  
  665.             rulelen := 0;
  666.  
  667.             current_state_enum := STATE_TRAILING_CONTEXT;
  668.             
  669. yyval := 
  670. yy.value_stack(yy.tos-1);
  671.             
  672.  
  673. when  32 =>
  674. --#line  379
  675.  
  676.             -- this is where concatenation of adjacent patterns
  677.             -- gets done
  678.  
  679.             
  680. yyval := nfa.link_machines( 
  681. yy.value_stack(yy.tos-1), 
  682. yy.value_stack(yy.tos) );
  683.             
  684.  
  685. when  33 =>
  686. --#line  387
  687.  
  688. yyval := 
  689. yy.value_stack(yy.tos); 
  690.  
  691. when  34 =>
  692. --#line  391
  693.  
  694.             varlength := true;
  695.  
  696.             
  697. yyval := nfa.mkclos( 
  698. yy.value_stack(yy.tos-1) );
  699.             
  700.  
  701. when  35 =>
  702. --#line  398
  703.  
  704.             varlength := true;
  705.  
  706.             
  707. yyval := nfa.mkposcl( 
  708. yy.value_stack(yy.tos-1) );
  709.             
  710.  
  711. when  36 =>
  712. --#line  405
  713.  
  714.             varlength := true;
  715.  
  716.             
  717. yyval := nfa.mkopt( 
  718. yy.value_stack(yy.tos-1) );
  719.             
  720.  
  721. when  37 =>
  722. --#line  412
  723.  
  724.             varlength := true;
  725.  
  726.             if ( (
  727. yy.value_stack(yy.tos-3) > 
  728. yy.value_stack(yy.tos-1)) or (
  729. yy.value_stack(yy.tos-3) < 0) ) then
  730.                 misc.synerr( "bad iteration values" );
  731.                 
  732. yyval := 
  733. yy.value_stack(yy.tos-5);
  734.             else
  735.                 if ( 
  736. yy.value_stack(yy.tos-3) = 0 ) then
  737.                 
  738. yyval := nfa.mkopt( nfa.mkrep( 
  739. yy.value_stack(yy.tos-5), 
  740. yy.value_stack(yy.tos-3), 
  741. yy.value_stack(yy.tos-1) ) );
  742.                 else
  743.                 
  744. yyval := nfa.mkrep( 
  745. yy.value_stack(yy.tos-5), 
  746. yy.value_stack(yy.tos-3), 
  747. yy.value_stack(yy.tos-1) );
  748.                 end if;
  749.                         end if;
  750.             
  751.  
  752. when  38 =>
  753. --#line  428
  754.  
  755.             varlength := true;
  756.  
  757.             if ( 
  758. yy.value_stack(yy.tos-2) <= 0 ) then
  759.                 misc.synerr( "iteration value must be positive" );
  760.                 
  761. yyval := 
  762. yy.value_stack(yy.tos-4);
  763.             else
  764.                 
  765. yyval := nfa.mkrep( 
  766. yy.value_stack(yy.tos-4), 
  767. yy.value_stack(yy.tos-2), INFINITY );
  768.             end if;    
  769.             
  770.  
  771. when  39 =>
  772. --#line  440
  773.  
  774.             -- the singleton could be something like "(foo)",
  775.             -- in which case we have no idea what its length
  776.             -- is, so we punt here.
  777.  
  778.             varlength := true;
  779.  
  780.             if ( 
  781. yy.value_stack(yy.tos-1) <= 0 ) then
  782.                 misc.synerr( "iteration value must be positive" );
  783.                 
  784. yyval := 
  785. yy.value_stack(yy.tos-3);
  786.             else
  787.                 
  788. yyval := nfa.link_machines( 
  789. yy.value_stack(yy.tos-3), nfa.copysingl( 
  790. yy.value_stack(yy.tos-3), 
  791. yy.value_stack(yy.tos-1) - 1 ) );
  792.             end if;    
  793.             
  794.  
  795. when  40 =>
  796. --#line  456
  797.  
  798.             if ( not madeany ) then
  799.                 -- create the '.' character class
  800.                 anyccl := ccl.cclinit;
  801.                 ccl.ccladd( anyccl, ASCII.LF );
  802.                 ccl.cclnegate( anyccl );
  803.  
  804.                 if ( useecs ) then
  805.                 ecs.mkeccl(
  806.                ccltbl(cclmap(anyccl)..cclmap(anyccl) + ccllen(anyccl)),
  807.                     ccllen(anyccl), nextecm,
  808.                     ecgroup, CSIZE );
  809.                 end if;
  810.                 madeany := true;
  811.                         end if;
  812.  
  813.             rulelen := rulelen + 1;
  814.  
  815.             
  816. yyval := nfa.mkstate( -anyccl );
  817.             
  818.  
  819. when  41 =>
  820. --#line  478
  821.  
  822.             if ( not cclsorted ) then
  823.                 -- sort characters for fast searching.  We use a
  824.                 -- shell sort since this list could be large.
  825.  
  826. --                misc.cshell( ccltbl + cclmap($1), ccllen($1) );
  827.               misc.cshell( ccltbl(cclmap(
  828. yy.value_stack(yy.tos))..cclmap(
  829. yy.value_stack(yy.tos)) + ccllen(
  830. yy.value_stack(yy.tos))),
  831.                    ccllen(
  832. yy.value_stack(yy.tos)) );
  833.             end if;
  834.  
  835.             if ( useecs ) then
  836.             ecs.mkeccl( ccltbl(cclmap(
  837. yy.value_stack(yy.tos))..cclmap(
  838. yy.value_stack(yy.tos)) + ccllen(
  839. yy.value_stack(yy.tos))),
  840.                 ccllen(
  841. yy.value_stack(yy.tos)),nextecm, ecgroup, CSIZE );
  842.             end if;
  843.                      
  844.             rulelen := rulelen + 1;
  845.  
  846.             
  847. yyval := nfa.mkstate( -
  848. yy.value_stack(yy.tos) );
  849.             
  850.  
  851. when  42 =>
  852. --#line  499
  853.  
  854.             rulelen := rulelen + 1;
  855.  
  856.             
  857. yyval := nfa.mkstate( -
  858. yy.value_stack(yy.tos) );
  859.             
  860.  
  861. when  43 =>
  862. --#line  506
  863.  
  864. yyval := 
  865. yy.value_stack(yy.tos-1); 
  866.  
  867. when  44 =>
  868. --#line  509
  869.  
  870. yyval := 
  871. yy.value_stack(yy.tos-1); 
  872.  
  873. when  45 =>
  874. --#line  512
  875.  
  876.             rulelen := rulelen + 1;
  877.  
  878.             if ( 
  879. yy.value_stack(yy.tos) = CHARACTER'POS(ASCII.NUL) ) then
  880.                 misc.synerr( "null in rule" );
  881.             end if;    
  882.  
  883.             if ( caseins and (
  884. yy.value_stack(yy.tos) >= CHARACTER'POS('A')) and (
  885. yy.value_stack(yy.tos) <= CHARACTER'POS('Z')) ) then
  886.                 
  887. yy.value_stack(yy.tos) := misc.clower( 
  888. yy.value_stack(yy.tos) );
  889.             end if;
  890.  
  891.             
  892. yyval := nfa.mkstate( 
  893. yy.value_stack(yy.tos) );
  894.             
  895.  
  896. when  46 =>
  897. --#line  528
  898.  
  899. yyval := 
  900. yy.value_stack(yy.tos-1); 
  901.  
  902. when  47 =>
  903. --#line  531
  904.  
  905.             -- *Sigh* - to be compatible Unix lex, negated ccls
  906.             -- match newlines
  907.             ccl.cclnegate( 
  908. yy.value_stack(yy.tos-1) );
  909.             
  910. yyval := 
  911. yy.value_stack(yy.tos-1);
  912.             
  913.  
  914. when  48 =>
  915. --#line  540
  916.  
  917.             if ( 
  918. yy.value_stack(yy.tos-2) > 
  919. yy.value_stack(yy.tos) ) then
  920.                 misc.synerr( "negative range in character class" );
  921.             else
  922.                 if ( caseins ) then
  923.                 if ( (
  924. yy.value_stack(yy.tos-2) >= CHARACTER'POS('A')) and (
  925. yy.value_stack(yy.tos-2) <= CHARACTER'POS('Z')) ) then
  926.                     
  927. yy.value_stack(yy.tos-2) := misc.clower( 
  928. yy.value_stack(yy.tos-2) );
  929.                 end if;                        
  930.                 if ( (
  931. yy.value_stack(yy.tos) >= CHARACTER'POS('A')) and (
  932. yy.value_stack(yy.tos) <= CHARACTER'POS('Z')) ) then
  933.                     
  934. yy.value_stack(yy.tos) := misc.clower( 
  935. yy.value_stack(yy.tos) );
  936.                 end if;    
  937.                             end if;
  938.  
  939.                 for i in 
  940. yy.value_stack(yy.tos-2) .. 
  941. yy.value_stack(yy.tos) loop
  942.                     ccl.ccladd( 
  943. yy.value_stack(yy.tos-3), CHARACTER'VAL(i) );
  944.                             end loop;
  945.                 
  946.                 -- keep track if this ccl is staying in
  947.                 -- alphabetical order
  948.  
  949.                 cclsorted := cclsorted and (
  950. yy.value_stack(yy.tos-2) > lastchar);
  951.                 lastchar := 
  952. yy.value_stack(yy.tos);
  953.                         end if;
  954.             
  955.             
  956. yyval := 
  957. yy.value_stack(yy.tos-3);
  958.             
  959.  
  960. when  49 =>
  961. --#line  568
  962.  
  963.             if ( caseins ) then
  964.                 if ( (
  965. yy.value_stack(yy.tos) >= CHARACTER'POS('A')) and (
  966. yy.value_stack(yy.tos) <= CHARACTER'POS('Z')) ) then
  967.                 
  968. yy.value_stack(yy.tos) := misc.clower( 
  969. yy.value_stack(yy.tos) );
  970.                             end if;
  971.             end if;    
  972.             ccl.ccladd( 
  973. yy.value_stack(yy.tos-1), CHARACTER'VAL(
  974. yy.value_stack(yy.tos)) );
  975.             cclsorted := cclsorted and (
  976. yy.value_stack(yy.tos) > lastchar);
  977.             lastchar := 
  978. yy.value_stack(yy.tos);
  979.             
  980. yyval := 
  981. yy.value_stack(yy.tos-1);
  982.             
  983.  
  984. when  50 =>
  985. --#line  581
  986.  
  987.             cclsorted := true;
  988.             lastchar := 0;
  989.             
  990. yyval := ccl.cclinit;
  991.             
  992.  
  993. when  51 =>
  994. --#line  589
  995.  
  996.             if ( caseins ) then
  997.                 if ( (
  998. yy.value_stack(yy.tos) >= CHARACTER'POS('A')) and (
  999. yy.value_stack(yy.tos) <= CHARACTER'POS('Z')) ) then
  1000.                 
  1001. yy.value_stack(yy.tos) := misc.clower( 
  1002. yy.value_stack(yy.tos) );
  1003.                 end if;
  1004.             end if;    
  1005.  
  1006.             rulelen := rulelen + 1;
  1007.  
  1008.             
  1009. yyval := nfa.link_machines( 
  1010. yy.value_stack(yy.tos-1), nfa.mkstate( 
  1011. yy.value_stack(yy.tos) ) );
  1012.             
  1013.  
  1014. when  52 =>
  1015. --#line  602
  1016.  
  1017. yyval := nfa.mkstate( SYM_EPSILON ); 
  1018.  
  1019.                 when others => null;
  1020.             end case;
  1021.  
  1022.             -- Pop RHS states and goto next state
  1023.             yy.tos      := yy.tos - rule_length(yy.rule_id) + 1;
  1024.             if yy.tos > yy.stack_size then
  1025.                 put_line(" Stack size exceeded on state_stack");
  1026.                 raise yy_Tokens.syntax_error;
  1027.             end if;
  1028.             yy.state_stack(yy.tos) := goto_state(yy.state_stack(y@tos-1) ,
  1029.                                  get_lhs_rule(yy.rule_id));
  1030.  
  1031.             yy.value_stack(yy.tos) := yyval;
  1032.  
  1033.             if yy.debug then
  1034.                 reduce_debug(yy.rule_id,
  1035.                     goto_state(yy.state_stack(yy.tos - 1),
  1036.                                get_lhs_rule(yy.rule_id)));
  1037.             end if;
  1038.  
  1039.         end if;
  1040.     end loop;
  1041.  
  1042. end yyparse;
  1043. end parser;
  1044.